﻿using System;
using System.Collections.Generic;
using System.Data;
using IBatisNet.DataMapper;

namespace Carson.DataAccess
{
    public class DbHelper
    {
        private static DbHelper _dbHelper;
        private ISqlMapper _sqlMapper;

        public static DbHelper Singleton()
        {
            if (_dbHelper == null)
            {
                lock (typeof(DbHelper))
                {
                    if (_dbHelper == null) // double-check
                    {
                        _dbHelper = new DbHelper();
                        _dbHelper.SetSqlMapper(Mapper.Get());
                    }
                }
            }
            return _dbHelper;
        }

        public void SetSqlMapper(ISqlMapper sqlMapper)
        {
            _sqlMapper = sqlMapper;
        }

        public ISqlMapSession BeginTransaction()
        {
            return _sqlMapper.BeginTransaction();

        }

        public void RollBackTransaction()
        {
            _sqlMapper.RollBackTransaction();
        }

        public PageModel<T> QueryPageList<T>(String statementName, Object parameter, int pageNum, int pageSize, string sidx, string sord)
        {
            int startIndex = (pageNum - 1) * pageSize;
            IList<T> list = IBatisExt.QueryForPageList<T>(_sqlMapper, statementName, parameter, startIndex, pageSize, sidx, sord);
            int total = IBatisExt.QueryCount(_sqlMapper, statementName, parameter);
            PageModel<T> pageModel = new PageModel<T>
            {
                TotalPages = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1),
                TotalRecords = total,
                Rows = list
            };
            return pageModel;
        }

        public PageModel<T> QueryPageList<T>(String statementName, QueryParam qp)
        {
            return QueryPageList<T>(statementName, qp, qp.PageNum, qp.PageSize, qp.SortIndex, qp.SortOrder);
        }

        public PageTableModel QueryPageTable(String statementName, Object parameter, int pageNum, int pageSize, string sidx, string sord)
        {
            int startIndex = (pageNum - 1) * pageSize;
            DataTable table = IBatisExt.QueryForPageTable(_sqlMapper, statementName, parameter, startIndex, pageSize, sidx, sord);
            int total = IBatisExt.QueryCount(_sqlMapper, statementName, parameter);
            PageTableModel pageModel = new PageTableModel
            {
                TotalPages = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize + 1),
                TotalRecords = total,
                Rows = table
            };
            return pageModel;
        }

        public DataTable QueryDataTable(String statementName, object parameterObject = null)
        {
            return _sqlMapper.QueryForDataTable(statementName, parameterObject);
        }

        public PageTableModel QueryPageTable(String statementName, QueryParam qp)
        {
            return QueryPageTable(statementName, qp, qp.PageNum, qp.PageSize, qp.SortIndex, qp.SortOrder);
        }

        public IList<T> QueryList<T>(String statementName, object parameterObject = null)
        {
            return _sqlMapper.QueryForList<T>(statementName, parameterObject);
        }

        public T QueryOne<T>(String statementName, object parameterObject = null)
        {
            return _sqlMapper.QueryForObject<T>(statementName, parameterObject);
        }

        public IDictionary<K, V> QueryForDictionary<K, V>(String statementName, object parameterObject, string keyProperty, string valueProperty)
        {
            return _sqlMapper.QueryForDictionary<K, V>(statementName, parameterObject, keyProperty, valueProperty);
        }

        public void Insert(string statementName, object parameterObject)
        {
            _sqlMapper.Insert(statementName, parameterObject);
        }

        public void Update(string statementName, object parameterObject)
        {
            _sqlMapper.Update(statementName, parameterObject);
        }

        public void Delete(string statementName, object parameterObject)
        {
            _sqlMapper.Delete(statementName, parameterObject);
        }

        public int InsertEntity<T>(T parameterObject)
        {
            return IBatisExt.InsertEntity(_sqlMapper, parameterObject);
        }

        public int UpdateEntity<T>(T parameterObject)
        {
            return IBatisExt.UpdateEntity(_sqlMapper, parameterObject);
        }

        public int DeleteEntity<T>(T parameterObject)
        {
            return IBatisExt.DeleteEntity(_sqlMapper, parameterObject);
        }

        public int DeleteById<T>(object parameterObject)
        {
            return IBatisExt.DeleteById<T>(_sqlMapper, parameterObject);
        }
    }
}
